﻿#region

using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Windows;
using Rio.Framework.Localisation;
using Rio.Framework.WCFService;
using Rio.Framework.WCFService.RioWcfServices;

#endregion

namespace Rio.Framework.Pages.Manager
{
    public class PdfManager
    {
        #region Attribute

        private List<string> Lst_FileNameToMergeInPdf { get; set; }
        private Boolean MessageToLaunchTreatment { get; set; }
        private long UserId { get; set; }
        private string s_MergePdfQuestion { get; set; }

        #endregion Attribute

        #region Variables

        private int m_iCurrentIndextoFilenamesToConvert;
        private Guid m_oGuidSessionToConvert;

        #endregion Variables

        #region Event

        //Event raised when the imported documents has been merged and an error has occured

        #region Delegates

        public delegate void ImportedDocumentMergeFailedEventHandler(object sender, ImportedDocumentMergeFailedEventArgs args);

        public delegate void MergePDFCompletedEventHandler(object sender, MergePDFCompletedEventArgs args);

        #endregion

        #region Instance Methods

        protected void OnImportedDocumentMergeFailed(string p_sErrorFileName)
        {
            if (ImportedDocumentMergeFailed != null)
            {
                ImportedDocumentMergeFailed(this, new ImportedDocumentMergeFailedEventArgs());
            }
        }

        protected void OnMergePDFCompleted(string p_sPdfFileName)
        {
            if (MergePDFCompleted != null)
            {
                MergePDFCompleted(this, new MergePDFCompletedEventArgs(p_sPdfFileName, Lst_FileNameToMergeInPdf));
            }
        }

        #endregion

        #region Event Declarations

        public event ImportedDocumentMergeFailedEventHandler ImportedDocumentMergeFailed;
        public event MergePDFCompletedEventHandler MergePDFCompleted;

        #endregion

        #endregion Event

        #region Constructors

        /// <summary>
        ///   New Instance
        /// </summary>
        /// <param name="p_sLstFileNameToMergeInPdf"> </param>
        public PdfManager(List<string> p_sLstFileNameToTreat, Boolean p_bMessageToStartTreatment, long p_lUserCurrentId)
        {
            if ((p_sLstFileNameToTreat == null) || (p_sLstFileNameToTreat.Count == 0))
                throw new ArgumentNullException("p_sLstFileNameToMergeInPdf");

            //Initialize Instance.
            Lst_FileNameToMergeInPdf = p_sLstFileNameToTreat;
            s_MergePdfQuestion = Resx.GetLabel(ResxCommon.MERGE_PDF_QUESTION);
            MessageToLaunchTreatment = p_bMessageToStartTreatment;
            UserId = p_lUserCurrentId;
        }

        #endregion

        #region Merge In Pdf

        #region Instance Methods

        /// <summary>
        ///   Start treatment.
        /// </summary>
        public void MergeDocumentsListInPdf()
        {
            //Call pdf merge treatment.
            MergeDocumentsInPdf();
        }

        /// <summary>
        ///   Error.
        /// </summary>
        private void AbortMergePdf(WCFServiceClient L_oWCFServiceClient)
        {
            //Delete Temporary directory.
            L_oWCFServiceClient.DeleteTemporaryDirectoryAsync(m_oGuidSessionToConvert.ToString("N"), ServiceManager.GetLicenseKey());

            if (ImportedDocumentMergeFailed != null)
            {
                ImportedDocumentMergeFailedEventArgs args = new ImportedDocumentMergeFailedEventArgs();
                args.ErrorDocName = Lst_FileNameToMergeInPdf[m_iCurrentIndextoFilenamesToConvert];
                ImportedDocumentMergeFailed(this, args);
            }
        }

        /// <summary>
        ///   Converts the next document.
        /// </summary>
        /// <param name="L_oWCFServiceClient"> The l_o WCF service client. </param>
        private void ConvertNextDocument2(WCFServiceClient L_oWCFServiceClient)
        {
            //Increment index
            m_iCurrentIndextoFilenamesToConvert++;

            if (m_iCurrentIndextoFilenamesToConvert < Lst_FileNameToMergeInPdf.Count)
            {
                //Continue converting with next document
                L_oWCFServiceClient.ConvertDocumentAppendCompleted += L_oWCFServiceClient_ConvertDocumentAppendCompleted2;
                L_oWCFServiceClient.ConvertDocumentAppendAsync(m_oGuidSessionToConvert.ToString("N"), Lst_FileNameToMergeInPdf[m_iCurrentIndextoFilenamesToConvert], UserId,
                                                               ServiceManager.GetLicenseKey(), true);
            }
            else
            {
                //IF there is items who need finalizing
                if (Lst_FileNameToMergeInPdf.Count > 0)
                {
                    //Finalize converting
                    L_oWCFServiceClient.ConvertDocumentFinishCompleted += L_oWCFServiceClient_ConvertDocumentFinishCompleted2;
                    L_oWCFServiceClient.ConvertDocumentFinishAsync(m_oGuidSessionToConvert.ToString("N"), UserId, ServiceManager.GetLicenseKey(), false);
                }
                else
                {
                    AbortMergePdf(L_oWCFServiceClient);
                }
            }
        }

        /// <summary>
        ///   Launch the pdf merge.
        /// </summary>
        private void MergeDocumentsInPdf()
        {
            //Start Processing.
            if (Lst_FileNameToMergeInPdf != null && Lst_FileNameToMergeInPdf.Count > 0)
            {
                if (MessageToLaunchTreatment)
                {
                    MessageBoxChildWindow L_oMessagesMergePdf = new MessageBoxChildWindow("", s_MergePdfQuestion, MessageBoxButtons.YesNo, MessageBoxIcon.Question);
                    L_oMessagesMergePdf.Show();

                    L_oMessagesMergePdf.Closed += (s, ev) =>
                                                      {
                                                          if (L_oMessagesMergePdf.Result == MessageBoxResult.Yes)
                                                          {
                                                              StartPdfMerge();
                                                          }
                                                      };
                }
                else
                {
                    StartPdfMerge();
                }
            }
        }

        /// <summary>
        ///   Start the pdf merge.
        /// </summary>
        private void StartPdfMerge()
        {
            //This is a new converting, so we generate a new Guid.
            m_oGuidSessionToConvert = Guid.NewGuid();

            //call WCF to prepare converting.
            WCFServiceClient L_oWCFServiceClient = ServiceManager.GetRioWCFServiceClient();
            L_oWCFServiceClient.CreateTemporaryDirectoryCompleted += L_oWCFServiceClient_CreateTemporaryDirectoryCompleted2;
            L_oWCFServiceClient.CreateTemporaryDirectoryAsync(m_oGuidSessionToConvert.ToString("N"), ServiceManager.GetLicenseKey());
        }

        #endregion

        #region Event Handling

        /// <summary>
        ///   Handles the ConvertDocumentAppendCompleted2 event of the L_oWCFServiceClient control.
        /// </summary>
        /// <param name="sender"> </param>
        /// <param name="e"> </param>
        private void L_oWCFServiceClient_ConvertDocumentAppendCompleted2(object sender, ConvertDocumentAppendCompletedEventArgs e)
        {
            WCFServiceClient L_oWCFServiceClient = ServiceManager.GetRioWCFServiceClient();

            if (e.Result.IsValid)
            {
                ConvertNextDocument2(L_oWCFServiceClient);
            }
            else
            {
                //Treat error.
                MessageBoxChildWindow errorMessageBox = new MessageBoxChildWindow(
                    String.Empty,
                    String.Format(Resx.GetLabel(ResxCommon.FORMAT_ERROR_WHILE_PROCESSING), Lst_FileNameToMergeInPdf[m_iCurrentIndextoFilenamesToConvert]),
                    MessageBoxButtons.YesNo,
                    MessageBoxIcon.Question);

                errorMessageBox.Show();
                errorMessageBox.Closed += (s, ev) =>
                                              {
                                                  if (errorMessageBox.DialogResult == true)
                                                  {
                                                      //Set null on error document from files to convert to avoid deleting at finish
                                                      Lst_FileNameToMergeInPdf[m_iCurrentIndextoFilenamesToConvert] = null;

                                                      //Skip & continue transfert
                                                      ConvertNextDocument2(L_oWCFServiceClient);
                                                  }
                                                  else
                                                  {
                                                      AbortMergePdf(L_oWCFServiceClient);
                                                  }
                                              };
            }
        }

        /// <summary>
        ///   Handles the ConvertDocumentFinishCompleted2 event of the L_oWCFServiceClient control.
        /// </summary>
        /// <param name="sender"> The source of the event. </param>
        /// <param name="e"> The <see cref="Rio.Framework.WCFService.RioWcfServices.ConvertDocumentFinishCompletedEventArgs" /> instance containing the event data. </param>
        private void L_oWCFServiceClient_ConvertDocumentFinishCompleted2(object sender, ConvertDocumentFinishCompletedEventArgs e)
        {
            WCFServiceClient L_oWCFServiceClient = ServiceManager.GetRioWCFServiceClient();

            //Delete temporary directory
            L_oWCFServiceClient.DeleteTemporaryDirectoryCompleted += (s, ev) =>
                                                                         {
                                                                             //Delete all imported document who have been converted
                                                                             L_oWCFServiceClient = ServiceManager.GetRioWCFServiceClient();

                                                                             L_oWCFServiceClient.DeleteImportDocumentCompleted += (o, ew) => { Lst_FileNameToMergeInPdf.Clear(); };

                                                                             //Delete import document converted.
                                                                             L_oWCFServiceClient.DeleteImportDocumentAsync(new ObservableCollection<string>(Lst_FileNameToMergeInPdf), UserId,
                                                                                                                           ServiceManager.GetLicenseKey());
                                                                         };

            //Delete temporary file.
            L_oWCFServiceClient.DeleteTemporaryDirectoryAsync(m_oGuidSessionToConvert.ToString("N"), ServiceManager.GetLicenseKey());

            //Retrieves New name of file converted in pdf.
            OnMergePDFCompleted(e.Result.Value);
        }

        /// <summary>
        ///   Create temporary directory.
        /// </summary>
        /// <param name="sender"> </param>
        /// <param name="e"> </param>
        private void L_oWCFServiceClient_CreateTemporaryDirectoryCompleted2(object sender, CreateTemporaryDirectoryCompletedEventArgs e)
        {
            //Clean and prepare objects to converting
            m_iCurrentIndextoFilenamesToConvert = 0;
            WCFServiceClient L_oWCFServiceClient = ServiceManager.GetRioWCFServiceClient();

            if (e.Result.IsValid)
            {
                //Retry selected documents according to allowed extensions
                if (Lst_FileNameToMergeInPdf != null && Lst_FileNameToMergeInPdf.Count > 0)
                {
                    //Launch converting                    
                    L_oWCFServiceClient.ConvertDocumentAppendCompleted += L_oWCFServiceClient_ConvertDocumentAppendCompleted2;
                    L_oWCFServiceClient.ConvertDocumentAppendAsync(m_oGuidSessionToConvert.ToString("N"), Lst_FileNameToMergeInPdf[m_iCurrentIndextoFilenamesToConvert], UserId,
                                                                   ServiceManager.GetLicenseKey(), true);
                }
            }
            else
            {
                AbortMergePdf(L_oWCFServiceClient);
            }
        }

        #endregion

        #endregion Merge In Pdf
    }

    #region Completed and Failled pdf merge

    /// <summary>
    ///   Event Merge pdf file Completed.
    /// </summary>
    public class MergePDFCompletedEventArgs
        : EventArgs
    {
        #region Constructors

        public MergePDFCompletedEventArgs(string PdfFileName)
        {
            this.PdfFileName = PdfFileName;
        }

        public MergePDFCompletedEventArgs(string PdfFileName, List<string> FileNameMerged)
        {
            this.PdfFileName = PdfFileName;
            this.FileNameMerged = FileNameMerged;
        }

        #endregion

        #region Instance Properties

        public string PdfFileName { get; set; }
        public List<string> FileNameMerged { get; set; }

        #endregion
    }

    /// <summary>
    ///   Event Merge pdf error.
    /// </summary>
    public class ImportedDocumentMergeFailedEventArgs
        : EventArgs
    {
        #region Constructors

        public ImportedDocumentMergeFailedEventArgs()
        {
            ErrorDocName = ErrorDocName;
            Cancel = true;
        }

        #endregion

        #region Instance Properties

        public Boolean Cancel { get; set; }
        public string ErrorDocName { get; set; }

        #endregion
    }

    #endregion Completed and Failled pdf merge
}